#!/usr/bin/env node

/**
 * 填充已预约状态数据的预约成功时间
 *
 * 对于状态为 'booked' 但 booked_at 为 null 的记录，使用 updated_at 来填充 booked_at
 *
 * 使用方法：
 *   node app/scripts/fill-booked-at-from-updated-at.mjs
 *   node app/scripts/fill-booked-at-from-updated-at.mjs --dry-run
 *   node app/scripts/fill-booked-at-from-updated-at.mjs --db-path "C:\path\to\app.db"
 */

import { existsSync } from 'node:fs'
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'

const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
const projectRoot = join(__dirname, '..')

async function main() {
  // 解析命令行参数
  let dryRun = false
  let specifiedDbPath = null

  for (let i = 2; i < process.argv.length; i++) {
    const arg = process.argv[i]
    if (arg === '--dry-run') {
      dryRun = true
    }
    else if (arg === '--db-path' && i + 1 < process.argv.length) {
      specifiedDbPath = process.argv[i + 1]
      i++
    }
  }

  if (dryRun) {
    console.log('🔍 预览模式：不会实际修改数据\n')
  }

  // 初始化数据库
  console.log('正在初始化数据库...')
  const { PrismaClient } = await import('@prisma/client')

  let dbPath = null

  // 如果用户指定了数据库路径，直接使用
  if (specifiedDbPath) {
    if (existsSync(specifiedDbPath)) {
      dbPath = specifiedDbPath
      console.log(`使用指定的数据库文件: ${dbPath}`)
    }
    else {
      console.error(`❌ 指定的数据库文件不存在: ${specifiedDbPath}`)
      process.exit(1)
    }
  }
  else {
    // 尝试多个可能的数据库路径（优先使用生产环境）
    const possibleDbPaths = []

    // 如果是Windows，优先使用生产环境路径
    if (process.platform === 'win32') {
      // 优先使用生产环境实际路径
      possibleDbPaths.push('C:\\Users\\Administrator\\AppData\\Roaming\\AutoTools\\data\\app.db')

      const appData = process.env.APPDATA || process.env.LOCALAPPDATA
      if (appData) {
        // 使用AutoTools（生产环境实际使用的路径）
        possibleDbPaths.push(join(appData, 'AutoTools', 'data', 'app.db'))
        // 兼容其他可能的路径
        possibleDbPaths.push(join(appData, 'auto-tools', 'data', 'app.db'))
      }
    }

    // 最后尝试开发环境：项目目录下的数据库
    possibleDbPaths.push(join(projectRoot, 'prisma', 'data', 'app.db'))

    // 查找存在的数据库文件（按优先级顺序）
    console.log('正在查找数据库文件（按优先级）...')
    for (const path of possibleDbPaths) {
      if (existsSync(path)) {
        dbPath = path
        console.log(`✅ 找到数据库文件: ${dbPath}`)
        break
      }
      else {
        console.log(`  ⚠️  不存在: ${path}`)
      }
    }

    if (!dbPath) {
      console.error('\n❌ 未找到数据库文件，尝试了以下路径:')
      possibleDbPaths.forEach(p => console.error(`  - ${p}`))
      console.error('\n提示: 可以使用 --db-path 参数指定数据库文件路径')
      process.exit(1)
    }
  }

  const dbUrl = `file:${dbPath.replace(/\\/g, '/')}`
  process.env.DATABASE_URL = dbUrl

  const prisma = new PrismaClient({
    datasources: {
      db: { url: dbUrl },
    },
  })

  // 启用 WAL 模式
  try {
    await prisma.$executeRawUnsafe('PRAGMA journal_mode=WAL;')
    await prisma.$executeRawUnsafe('PRAGMA synchronous=NORMAL;')
    await prisma.$executeRawUnsafe('PRAGMA busy_timeout=15000;')
  }
  catch {}

  console.log(`✅ 数据库初始化完成: ${dbPath}`)
  console.log()

  try {
    // 查询需要修复的记录
    console.log('正在查询需要修复的记录...')
    const allRecords = await prisma.appointment_management.findMany({
      where: {
        appointment_status: 'booked',
        booked_at: null,
      },
      select: {
        id: true,
        sequence_number: true,
        full_name: true,
        appointment_status: true,
        booked_at: true,
        updated_at: true,
      },
      orderBy: {
        updated_at: 'asc',
      },
    })

    // 过滤掉 updated_at 为 null 的记录
    const recordsToFix = allRecords.filter(record => record.updated_at !== null)

    console.log(`找到 ${recordsToFix.length} 条需要修复的记录\n`)

    if (recordsToFix.length === 0) {
      console.log('✅ 没有需要修复的记录')
      return
    }

    // 显示前几条记录预览
    console.log('预览（前10条）:')
    console.log('─'.repeat(100))
    console.log(
      'ID'.padEnd(8),
      '序号'.padEnd(15),
      '姓名'.padEnd(20),
      '更新时间'.padEnd(20),
      '将设置的预约成功时间',
    )
    console.log('─'.repeat(100))
    recordsToFix.slice(0, 10).forEach((record) => {
      const updatedAt = record.updated_at ? new Date(record.updated_at).toISOString().replace('T', ' ').slice(0, 19) : '-'
      const bookedAt = record.updated_at ? new Date(record.updated_at).toISOString().replace('T', ' ').slice(0, 19) : '-'
      console.log(
        String(record.id).padEnd(8),
        (record.sequence_number || '-').padEnd(15),
        (record.full_name || '-').padEnd(20),
        updatedAt.padEnd(20),
        bookedAt,
      )
    })
    if (recordsToFix.length > 10) {
      console.log(`... 还有 ${recordsToFix.length - 10} 条记录`)
    }
    console.log('─'.repeat(100))
    console.log()

    if (dryRun) {
      console.log('🔍 预览模式：以上记录将使用 updated_at 填充 booked_at')
      console.log('运行时不加 --dry-run 参数将实际执行更新')
      return
    }

    // 确认操作
    console.log(`⚠️  即将更新 ${recordsToFix.length} 条记录的 booked_at 字段`)
    console.log('使用 updated_at 的值来填充 booked_at')
    console.log()

    // 执行批量更新
    console.log('正在更新...')
    let successCount = 0
    let failCount = 0

    // 使用批量更新提高效率
    const batchSize = 100
    for (let i = 0; i < recordsToFix.length; i += batchSize) {
      const batch = recordsToFix.slice(i, i + batchSize)

      try {
        // 构建批量更新条件
        const updates = batch
          .filter(record => record.updated_at !== null)
          .map(record => ({
            id: record.id,
            booked_at: record.updated_at,
          }))

        if (updates.length === 0) {
          continue
        }

        // 使用事务批量更新
        await prisma.$transaction(
          updates.map(update =>
            prisma.appointment_management.update({
              where: { id: update.id },
              data: { booked_at: update.booked_at },
            }),
          ),
        )

        successCount += updates.length
        const skipped = batch.length - updates.length
        if (skipped > 0) {
          failCount += skipped
        }

        if ((i + batchSize) % 500 === 0 || i + batchSize >= recordsToFix.length) {
          console.log(`  已处理 ${Math.min(i + batchSize, recordsToFix.length)}/${recordsToFix.length} 条...`)
        }
      }
      catch (error) {
        console.error(`❌ 批量更新失败 (批次 ${Math.floor(i / batchSize) + 1}):`, error.message)
        // 如果批量更新失败，尝试逐条更新
        console.log('  尝试逐条更新...')
        for (const record of batch) {
          try {
            if (!record.updated_at) {
              failCount++
              continue
            }
            await prisma.appointment_management.update({
              where: { id: record.id },
              data: { booked_at: record.updated_at },
            })
            successCount++
          }
          catch (err) {
            console.error(`  ❌ 更新记录 ID=${record.id} 失败:`, err.message)
            failCount++
          }
        }
      }
    }

    console.log()
    console.log('─'.repeat(100))
    console.log('✅ 更新完成！')
    console.log(`   成功: ${successCount} 条`)
    console.log(`   失败: ${failCount} 条`)
    console.log(`   总计: ${recordsToFix.length} 条`)
    console.log('─'.repeat(100))
  }
  catch (error) {
    console.error('❌ 执行失败:', error)
    process.exit(1)
  }
  finally {
    await prisma.$disconnect()
  }
}

main().catch((error) => {
  console.error('❌ 脚本执行失败:', error)
  process.exit(1)
})
